package com.xaicode.auth.security;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import com.xaicode.auth.security.domain.SatokenResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 全局认证异常处理
 * <p>
 * 本类异常基于 SaToken 框架
 * 
 * @date 2024/12/19
 */
@Slf4j
@RestControllerAdvice
public class GlobalAuthSaTokenExceptionHandler {

    /**
     * 基于 SaToken 框架的 token 相关异常处理
     *
     * @param ex   .
     * @param req  .
     * @param resp .
     * @return .
     */
    @ExceptionHandler(NotLoginException.class)
    public SatokenResult<?> notLoginException(NotLoginException ex, HttpServletRequest req, HttpServletResponse resp) {
        String message;
        switch (ex.getType()) {
            case NotLoginException.NOT_TOKEN:
                message = "无法读取有效令牌";
                break;
            case NotLoginException.INVALID_TOKEN:
                message = "令牌无效";
                break;
            case NotLoginException.TOKEN_TIMEOUT:
                message = "令牌已过期";
                break;
            case NotLoginException.BE_REPLACED:
                message = "令牌已被替换";
                break;
            case NotLoginException.KICK_OUT:
                message = "Token已被踢出";
                break;
            default:
                message = "未登录";
        }
        return SatokenResult.fail(401, message);
    }

    /**
     * 基于 SaToken 框架的无权限异常处理
     *
     * @param ex   .
     * @param req  .
     * @param resp .
     * @return .
     */
    @ExceptionHandler(NotPermissionException.class)
    public SatokenResult<?> notPermissionException(NotPermissionException ex, HttpServletRequest req, HttpServletResponse resp) {
        return SatokenResult.fail(403, ex.getMessage());
    }

    /**
     * 基于 SaToken 框架的无角色异常处理
     *
     * @param ex   .
     * @param req  .
     * @param resp .
     * @return .
     */
    @ExceptionHandler(NotRoleException.class)
    public SatokenResult<?> notRoleException(NotRoleException ex, HttpServletRequest req, HttpServletResponse resp) {
        return SatokenResult.fail(403, ex.getMessage());
    }

}
